import ByteBuffer = require("bytebuffer");


export default class Packet {
	public packetId: number = 0;

	private _buffer: ByteBuffer;


	constructor(buffer?: ByteBuffer) {
		this._buffer = buffer ? buffer : new ByteBuffer();
	}


	public Encode(packetId: number): void {
		var all = new ByteBuffer(4 + this._buffer.offset);
		all.writeUint16(this._buffer.offset + 2);
		all.writeUint16(packetId);
		all.append(this._buffer.slice(0, this._buffer.offset));
		this._buffer = all;
	}

	public Buffer(): Buffer {
		return this._buffer.slice(0, this._buffer.offset).buffer
	}

	public GetBuffer(): ByteBuffer {
		return this._buffer;
	}

	public WriteBuffer(v: ByteBuffer) {
		this._buffer.append(v.slice(0, v.offset));
	}

	public Reset(): void {
		this._buffer.reset();
	}


	public WriteByte(v: number) {
		this._buffer.writeUint8(v);
	}

	public WriteSbyte(v: number) {
		this._buffer.writeInt8(v);
	}

	public WriteUshort(v: number) {
		this._buffer.writeUint16(v);
	}

	public WriteShort(v: number) {
		this._buffer.writeInt16(v);
	}

	public WriteUint(v: number) {
		this._buffer.writeUint32(v);
	}

	public WriteInt(v: number) {
		this._buffer.writeInt32(v);
	}

	public WriteUlong(v) {
		this._buffer.writeUint64(v);
	}

	public WriteLong(v) {
		this._buffer.writeInt64(v);
	}

	public WriteFloat(v: number) {
		this._buffer.writeFloat32(v);
	}

	public WriteDouble(v: number) {
		this._buffer.writeFloat64(v);
	}

	public WriteString(v: string) {
		var len = ByteBuffer.calculateUTF8Bytes(v);
		this.WriteUshort(len);
		this._buffer.writeString(v);
	}


	public ReadByte(): number {
		return this._buffer.readUint8();
	}

	public ReadSbyte(): number {
		return this._buffer.readInt8();
	}

	public ReadUshort(): number {
		return this._buffer.readUint16();
	}

	public ReadShort(): number {
		return this._buffer.readInt16();
	}

	public ReadUint(): number {
		return this._buffer.readUint32();
	}

	public ReadInt(): number {
		return this._buffer.readInt32();
	}

	public ReadUlong() {
		return this._buffer.readUint64();
	}

	public ReadLong() {
		return this._buffer.readInt64();
	}

	public ReadFloat(): number {
		return this._buffer.readFloat32();
	}

	public ReadDouble(): number {
		return this._buffer.readFloat64();
	}

	public ReadString(): string {
		var len = this.ReadUshort();
		return this._buffer.readString(len, ByteBuffer.METRICS_BYTES);
	}
}
